package org.komarichin.jdo.dao;

import org.apache.commons.lang.StringUtils;
import org.komarichin.Constants;
import org.komarichin.beans.IGenericEntity;
import org.komarichin.beans.dao.IGenericDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.jdo.support.JdoDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import javax.jdo.Query;
import java.util.Collection;

/**
 * User: Mykhaylo Komarichyn
 * Date: 17.03.2010
 * Time: 11:35:40
 */
@Transactional(readOnly = true)
public abstract class JdoGenericDAOSupport<T extends IGenericEntity<PK>, PK>
        extends JdoDaoSupport
        implements IGenericDAO<T, PK> {
    private static final Logger log = LoggerFactory.getLogger(JdoGenericDAOSupport.class);
    private final Class<T> type;

    protected JdoGenericDAOSupport(Class<T> type) {
        this.type = type;
    }

    protected Class<T> getType() {
        return type;
    }

    @Override
    @Transactional(readOnly = false)
    public T save(T entity) {
        log.info("save entity: {}", entity);
        return getJdoTemplate().makePersistent(entity);
    }


    @Override
    public PK saveOrUpdate(T entity) {
        log.debug("save or update entity: {}", entity);
        T ft = getJdoTemplate().getObjectById(type, entity.getId());
        PK pk = null;
        if (ft == null) {
            ft = save(entity);
            if (ft != null) pk = ft.getId();
        }
        return pk;
    }


    @Override
    @Transactional(readOnly = false)
    public void remove(PK id) {
        log.debug("remove entity by id: {}", id);
        T ft = getJdoTemplate().getObjectById(type, id);
        log.info("remove entity: {}", ft);
        getJdoTemplate().deletePersistent(ft);
    }

    @Override
    public T findById(PK id) {
        log.debug("find entity by id: {}", id);
        T ft = getJdoTemplate().getObjectById(type, id);
        log.info("found entity: {}", id);
        return ft;
    }

    @Override
    public Collection<T> getAll() {
        log.debug("get all entities");
        Collection<T> result = getJdoTemplate().find(type);
        result.size();
        log.debug("result size: {}", result.size());
        return result;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Collection<T> getEntityByParams(int start, int limit, String fieldName, boolean order) {
        log.debug("get entities# start: {}, limit: {}, field: {}, order: {}", new Object[]{start, limit, fieldName, order});
        StringBuilder buff = new StringBuilder();
        if (StringUtils.isNotBlank(fieldName)) {
            buff.append(fieldName);
        } else {
            buff.append(" id ");
        }
        buff.append(order ? " asc " : " desc ");

        if (limit == 0) {
            limit = Constants.DISPLAY_LIMIT;
        }

        log.debug("query string: {}", buff.toString());

        Query query = getPersistenceManager().newQuery(type);

        query.setOrdering(buff.toString());
        query.setRange(start, start + limit);
        Collection<T> result = (Collection<T>) query.execute();
        result.size();
        log.info("query: {}, result size: {}", buff.toString(), result.size());
        return result;
    }

    @Override
    public int getCountEntities() {
        int result = getAll().size();
        log.info("get count entities# result: {}", result);
        return result;
    }

}
